/*
Problem Description
一批幸福的列车即将从杭州驶向幸福的终点站——温州，身为总列车长的linle有一些奇怪的癖好。

他会记录下全部乘客的名字（name）和他们的人品值（RP），根据这些将他们排序，
并不时地从某辆列车里踢出人品最不好（RP值最低）的一个人，当两个人人品一样不好时，
他就会踢出名字难听的人（linle认为按字典顺序，排在越在后面的人名字越难听）。

当然出于列车行驶需要，他还会不时的发布一些命令，比如让某个乘客上车，合并某两辆列车等。

Input
本题包含多组测试，请处理到文件结束。
对于每一组测试，第一行包含两个整数 N ，M ，表示一共有N( N<=10000 ) 辆列车，执行M( M<=10000 )次操作。
接下来有 N （从1开始记数）辆列车的信息，每辆列车先有一个数字 Xi(1 <= Xi <= 100 )，表示该列车有Xi个乘客，
接下来Xi行乘客信息，每个乘客包含名字（20个字符以内，不包含空白符）和人品（0<= RP <=30000）。
再接下来有 M 行操作信息，一共有3种操作，分别为

GETON Xi name RP 表示有一个叫name的人品为RP的人登上第Xi列车

JOIN Xi Xj 表示有将第Xj辆列车合并到Xi辆列车

GETOUT Xi 表示从第Xi辆列车踢出一个人品最差的人

测试数据保证每个操作均合法，即不会将已经被合并到其他列车的列车再进行合并，也不会从一辆空列车里踢出乘客
Output
对于每个 GETOUT 命令，输出被踢出的那个人的名字
Sample Input
3 5
2
xhd 0
zl 1
2
8600 1
ll 2
1
Ignatius 3
GETOUT 1
JOIN 1 2
GETOUT 1
GETON 3 hoho 2
GETOUT 3
Sample Output
xhd
zl
hoho
 */
package com.yuan.algorithms.training20150721;

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

class People {
	private String name;
	private int PRI;

	public People(String name, int PRI) {
		this.name = name;
		this.PRI = PRI;
	}
	
	public String getName() {
		return name;
	}

	public int getPRI() {
		return PRI;
	}

}

public class 优先队列_幸福列车 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		//排序规则
		Comparator<People> sort = new Comparator<People>() {

			@Override
			public int compare(People o1, People o2) {
				if (o1.getPRI() == o2.getPRI()) {
					//比较字符大小，并按逆序返回
					return -(o1.getName().compareTo(o2.getName()));
				}
				return o1.getPRI() > o2.getPRI() ? 1 : -1;
			}
		};
		Queue<People>[] queue = new PriorityQueue[10001];
		for (int i = 0; i < queue.length; i++) {
			queue[i] = new PriorityQueue<People>(sort);
		}
		while (sc.hasNext()) {
			int n = sc.nextInt();
			int m = sc.nextInt();
			for (int i = 0; i < n; i++) {
				int x = sc.nextInt();
				for (int j = 0; j < x; j++) {
					String name = sc.next();
					int rp = sc.nextInt();
					People t = new People(name, rp);
					queue[i].add(t);
				}
			}
			//接收指令
			for (int i = 0; i < m; i++) {
				String order = sc.next();
				if (order.equals("GETON")) {
					int index = sc.nextInt();
					String name = sc.next();
					int rp = sc.nextInt();
					People t = new People(name, rp);
					queue[index - 1].add(t);
				} else if (order.equals("JOIN")) {
					int a = sc.nextInt();
					int b = sc.nextInt();
					//合并队列
					while (!queue[b - 1].isEmpty()) {
						queue[a - 1].add(queue[b - 1].poll());
					}
				} else {
					int index = sc.nextInt();
					if(!queue[index-1].isEmpty()) {
						People k = queue[index-1].poll();
						System.out.println(k.getName());
					}
				}
			}
			//清空队列
			for (int i = 0; i < queue.length; i++) {
				while(!queue[i].isEmpty()) {
					queue[i].poll();
				}
			}
		}
	}
}
